package tenant

import (
	"context"
	constants2 "git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/utils"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/repository/common"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/vars"
	"gorm.io/gorm"
	"time"
)

type TenantsRepository struct {
	common.TenantServiceDB
}

func NewTenantsRepository() TenantsRepositoryIface {
	return &TenantsRepository{}
}

func (g *TenantsRepository) AddTenant(ctx context.Context, data *Tenants) (int32, error) {
	data.CreatedOn = time.Now()
	data.ModifiedOn = time.Now()
	err := g.GetTenantServiceDB(ctx).Create(&data).Error
	if err != nil {
		return 0, err
	}
	return data.Id, nil
}

func (g *TenantsRepository) SaveTenant(ctx context.Context, data *Tenants) error {
	data.ModifiedOn = time.Now()
	err := g.GetTenantServiceDB(ctx).Save(data).Error
	if err != nil {
		return err
	}
	return nil
}

func (g *TenantsRepository) GetTenantByCode(ctx context.Context, tenantCode string) (*Tenants, error) {
	tenants := &Tenants{}
	err := g.GetTenantServiceDB(ctx).
		Table(Tenants{}.TableName()).
		Where("is_deleted = ?", constants2.IsDeletedFalse).
		Where("code = ?", tenantCode).
		Order("created_on desc").First(tenants).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return tenants, err
	}
	return tenants, nil
}

func (g *TenantsRepository) GetTenantByName(ctx context.Context, name string) (*Tenants, error) {
	tenants := &Tenants{}
	err := g.GetTenantServiceDB(ctx).
		Table(Tenants{}.TableName()).
		Where("is_deleted = ?", constants2.IsDeletedFalse).
		Where("name = ?", name).
		Order("created_on desc").First(tenants).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return tenants, err
	}
	return tenants, nil
}

func (g *TenantsRepository) GetAllTenant(ctx context.Context) ([]*Tenants, error) {
	tenants := make([]*Tenants, 0)
	err := g.GetTenantServiceDB(ctx).
		Table(Tenants{}.TableName()).
		Where("is_deleted = ?", constants2.IsDeletedFalse).
		Order("created_on desc").Find(&tenants).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return tenants, err
	}
	return tenants, nil
}

func (g *TenantsRepository) GetAllEfficientTenant(ctx context.Context) (int64, []*Tenants, error) {
	tenants := make([]*Tenants, 0)
	err := g.GetTenantServiceDB(ctx).
		Select("a.code").
		Table(Tenants{}.TableName()+" as a").
		Joins("left join "+TenantsProfit{}.TableName()+" as b on a.code=b.tenant_code").
		Where("a.is_deleted = ?", constants2.IsDeletedFalse).
		Where("b.is_deleted = ?", constants2.IsDeletedFalse).
		Where("b.start_time < now() and b.end_time > now()").
		Group("a.code").
		Order("a.code desc").Find(&tenants).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return int64(len(tenants)), tenants, err
	}
	return int64(len(tenants)), tenants, nil
}

func (g *TenantsRepository) DisableTenant(ctx context.Context, tenantCode string) (bool, error) {
	err := g.GetTenantServiceDB(ctx).
		Table(Tenants{}.TableName()).
		Where("code=?", tenantCode).
		Where("is_deleted = ?", constants2.IsDeletedFalse).
		Updates(map[string]interface{}{"enabled": constants2.TenantDisabled}).Error
	if err != nil {
		return false, err
	}
	return true, nil
}

func (r *TenantsRepository) QueryTenantList(ctx context.Context, condition map[string]interface{}, pageInfo *utils.PageInfo, orderBy string) (int64, []*Tenants, error) {
	var result []*Tenants
	var count int64
	db := vars.TenantDBMySQLConn.GetClient()
	db = db.Table(Tenants{}.TableName()).Where(condition)
	err := db.Count(&count).Error
	if err != nil {
		return 0, nil, err
	}
	if pageInfo != nil && pageInfo.PageSize > 0 && pageInfo.Page > 0 {
		db = db.Offset((pageInfo.Page - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize)
	}

	if orderBy != "" {
		db = db.Order(orderBy)
	}

	err = db.Find(&result).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return 0, result, nil
		}
		return 0, nil, err
	}
	return count, result, nil
}
